home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectInput / DIConfig / flextooltip.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  6.5 KB  |  219 lines

  1. //-----------------------------------------------------------------------------
  2. // File: flextooltip.cpp
  3. //
  4. // Desc: Implements a tooltip class that displays a text string as a tooltip.
  5. //       CFlexTooltip (derived from CFlexWnd) is used throughout the UI when
  6. //       a control needs to have a tooltip.
  7. //
  8. // Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
  9. //-----------------------------------------------------------------------------
  10.  
  11. #include "common.hpp"
  12.  
  13. UINT_PTR CFlexToolTip::s_uiTimerID;
  14. DWORD CFlexToolTip::s_dwLastTimeStamp;  // Last time stamp for mouse move
  15. TOOLTIPINIT CFlexToolTip::s_TTParam;  // Parameters to initialize the tooltip
  16.  
  17. // TimerFunc is called periodically.  It checks if a tooltip should be displayed.
  18. // If a window has indicated a need for tooltip, TimerFunc will initialize
  19. // for displaying here.  CFlexWnd will do the actual displaying, since
  20. // it has to monitor WM_MOUSEMOVE message to be sure that tooltips only
  21. // display after a period of inactivity.
  22. void CALLBACK CFlexToolTip::TimerFunc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  23. {
  24.     // If it has been one sec already since last mouse move, display the tooltip
  25.     if (dwTime > CFlexWnd::s_dwLastMouseMove + 1000)
  26.     {
  27.         if (s_TTParam.hWndParent && !CFlexWnd::s_ToolTip.IsEnabled())
  28.         {
  29.             // Check if the mouse cursor is outside the window.  If so, don't activate tooltip.
  30.             POINT pt;
  31.             RECT rect;
  32.             GetCursorPos(&pt);
  33.             ScreenToClient(s_TTParam.hWndParent, &pt);
  34.             ::GetClientRect(s_TTParam.hWndParent, &rect);
  35.             if (!PtInRect(&rect, pt))
  36.                 return;
  37.  
  38.             SetParent(CFlexWnd::s_ToolTip.m_hWnd, s_TTParam.hWndParent);
  39.             CFlexWnd::s_ToolTip.SetSBWidth(s_TTParam.iSBWidth);
  40.             CFlexWnd::s_ToolTip.SetID(s_TTParam.dwID);
  41.             CFlexWnd::s_ToolTip.SetNotifyWindow(s_TTParam.hWndNotify);
  42.             CFlexWnd::s_ToolTip.SetText(s_TTParam.tszCaption);
  43.             CFlexWnd::s_ToolTip.SetEnable(TRUE);
  44.         }
  45.     }
  46. }
  47.  
  48. // We use the constructor and destructor to load and unload WINMM.DLL since the UI will only create this once.
  49.  
  50. CFlexToolTip::CFlexToolTip() :
  51.     m_tszText(NULL), m_hNotifyWnd(NULL), m_dwID(0), m_bEnabled(FALSE)
  52. {
  53. }
  54.  
  55. CFlexToolTip::~CFlexToolTip()
  56. {
  57.     delete[] m_tszText;
  58. }
  59.  
  60. HWND CFlexToolTip::Create(HWND hParent, const RECT &rect, BOOL bVisible, int iSBWidth)
  61. {
  62.     m_iSBWidth = iSBWidth;
  63.     return CFlexWnd::Create(hParent, rect, bVisible);
  64. }
  65.  
  66. // Set the tooltip position. pt is the upper-left point in screen coordinates.
  67. // bOffsetForMouseCursor is TRUE if the tooltip is to be displayed next to mouse cursor.  SetPosition()
  68. // will offset the position of the tooltip so that the cursor doesn't block the text of the tooltip.
  69. void CFlexToolTip::SetPosition(POINT pt, BOOL bOffsetForMouseCursor)
  70. {
  71.     // Check the top, right and bottom edges.  If they are outside the main config window
  72.     RECT rc;
  73.     RECT cliprc;
  74.     RECT parentrc;
  75.     GetWindowRect(GetParent(), &parentrc);
  76.     GetClientRect(&rc);
  77.     GetWindowRect(GetParent(), &cliprc);
  78.     cliprc.right -= DEFAULTVIEWSBWIDTH*2;
  79.     if (bOffsetForMouseCursor)
  80.     {
  81.         pt.y -= rc.bottom;  // Align the lower left corner to the cursor
  82.         pt.x += 1; pt.y -= 1;  // Offset x and y by 2 pixels so that when the mouse is moved up or right, we don't get over the tooltip window.
  83.     }
  84.     if (pt.y < cliprc.top) pt.y += cliprc.top - pt.y;  // Top
  85.     if (pt.x + rc.right > (cliprc.right - m_iSBWidth)) pt.x += cliprc.right - m_iSBWidth - (pt.x + rc.right);  // Right
  86.     if (pt.y + rc.bottom > cliprc.bottom) pt.y += cliprc.bottom - (pt.y + rc.bottom);  // Bottom
  87.     ScreenToClient(GetParent(), &pt);
  88.     SetWindowPos(m_hWnd, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE);
  89. }
  90.  
  91. void CFlexToolTip::SetText(LPCTSTR tszText, POINT *textpos)
  92. {
  93.     // Figure out window size and position
  94.     RECT rc = {0, 0, 320, 480};  // Only go to half the window width max
  95.     HDC hDC = CreateCompatibleDC(NULL);
  96.     if (hDC != NULL)
  97.     {
  98.         DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_CALCRECT);
  99.     //    DrawText(hDC, m_tszText, -1, &rc, DT_CALCRECT);
  100.         SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, 0);  // Set window pos as needed by text
  101.         DeleteDC(hDC);
  102.     }
  103.  
  104.     POINT pt;
  105.     if (textpos)
  106.     {
  107.         pt = *textpos;
  108.         SetPosition(pt, FALSE);
  109.     }
  110.     else
  111.     {
  112.         GetCursorPos(&pt);
  113.         SetPosition(pt);
  114.     }
  115.     SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, SWP_NOMOVE);  // Set size
  116. }
  117.  
  118. void CFlexToolTip::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
  119. {
  120.     ClientToScreen(m_hWnd, &point);
  121.     ScreenToClient(m_hNotifyWnd, &point);
  122.     if (bLeft)
  123.         PostMessage(m_hNotifyWnd, WM_LBUTTONDOWN, fwKeys, point.x | (point.y << 16));
  124.     else
  125.         PostMessage(m_hNotifyWnd, WM_RBUTTONDOWN, fwKeys, point.x | (point.y << 16));
  126. }
  127.  
  128. void CFlexToolTip::OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft)
  129. {
  130.     ClientToScreen(m_hWnd, &point);
  131.     ScreenToClient(m_hNotifyWnd, &point);
  132.     if (bLeft)
  133.         PostMessage(m_hNotifyWnd, WM_LBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
  134.     else
  135.         PostMessage(m_hNotifyWnd, WM_RBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
  136. }
  137.  
  138. void CFlexToolTip::OnPaint(HDC hDC)
  139. {
  140.     HDC hBDC = NULL, hODC = NULL;
  141.     CBitmap *pbm = NULL;
  142.  
  143.     if (!InRenderMode())
  144.     {
  145.         hODC = hDC;
  146.         pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
  147.         if (pbm != NULL)
  148.         {
  149.             hBDC = pbm->BeginPaintInto();
  150.             if (hBDC != NULL)
  151.             {
  152.                 hDC = hBDC;
  153.             }
  154.         }
  155.     }
  156.  
  157.     InternalPaint(hDC);
  158.  
  159.     if (!InRenderMode())
  160.     {
  161.         if (pbm != NULL)
  162.         {
  163.             if (hBDC != NULL)
  164.             {
  165.                 pbm->EndPaintInto(hBDC);
  166.                 pbm->Draw(hODC);
  167.             }
  168.             delete pbm;
  169.         }
  170.     }
  171. }
  172.  
  173. void CFlexToolTip::InternalPaint(HDC hDC)
  174. {
  175.     HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbBk);
  176.     if (hPen != NULL)
  177.     {
  178.         HGDIOBJ hOldPen = SelectObject(hDC, hPen);
  179.  
  180.         HGDIOBJ hBrush = CreateSolidBrush(m_rgbBk);
  181.         if (hBrush != NULL)
  182.         {
  183.             HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  184.             RECT rc = {0,0,0,0};
  185.  
  186.             GetClientRect(&rc);
  187.             DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_LEFT);
  188.  
  189.             SelectObject(hDC, hOldBrush);
  190.             DeleteObject(hBrush);
  191.         }
  192.  
  193.         SelectObject(hDC, hOldPen);
  194.         DeleteObject(hPen);
  195.     }
  196. }
  197.  
  198. LRESULT CFlexToolTip::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  199. {
  200.     return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
  201. }
  202.  
  203. LRESULT CFlexToolTip::OnCreate(LPCREATESTRUCT lpCreateStruct)
  204. {
  205.     // Create a timer
  206.     CFlexToolTip::s_uiTimerID = SetTimer(m_hWnd, 6, 50, CFlexToolTip::TimerFunc);
  207.     return 0;
  208. }
  209.  
  210. void CFlexToolTip::OnDestroy()
  211. {
  212.     // Kill the timer
  213.     if (CFlexToolTip::s_uiTimerID)
  214.     {
  215.         KillTimer(m_hWnd, 6);
  216.         CFlexToolTip::s_uiTimerID = 0;
  217.     }
  218. }
  219.